﻿using System;
using System.Collections.Generic;

namespace md.imi.membranes.objects.alphabet
{
    [Serializable]
    public class AlphabetObject : IDisposable
    {
        public string Data { get; set; }

        public List<int> Indexes { get; set; }

        public int Multiplicity { get; set; }

        /// <summary>
        /// 	Indicates if alpahbet object, is terminal or not
        /// </summary>
        public bool IsTerminal { get; set; }

        /// <summary>
        ///     Return string representation of underlying alphabet object
        /// </summary>
        /// <returns></returns>
        public override String ToString()
        {
            var result = "";

            if (String.IsNullOrWhiteSpace(Data)) return String.Empty;

            if (Indexes != null && Indexes.Count > 0)
            {
                foreach (var idx in Indexes)
                {
                    if (result.Length != 0) result += ", ";
                    result += idx.ToString();
                }
                result = "{" + result + "}";
            }

            if (Multiplicity > 1) result += "^" + Multiplicity;

            result = Data + result;
            return result;
        }

        #region Contructors

        /// <summary>
        ///     Default initialization contructor
        /// </summary>
        public AlphabetObject()
        {
            Multiplicity = 1;
            Indexes = new List<int>();
            Data = "";
        }

        /// <summary>
        ///     Initializa alphabet object with a value
        /// </summary>
        /// <param name="data"></param>
        public AlphabetObject(String data)
            : this()
        {
            Data = data;
        }

        /// <summary>
        ///     Initialize alphabet object with value and a multiplicity of this value
        /// </summary>
        /// <param name="data"></param>
        /// <param name="multiplicity"></param>
        public AlphabetObject(String data, int multiplicity)
            : this(data)
        {
            Multiplicity = multiplicity;
        }


        /// <summary>
        ///     Copy constructor
        /// </summary>
        /// <param name="ao"></param>
        public AlphabetObject(AlphabetObject ao)
            : this(ao.Data, ao.Multiplicity)
        {
         
            this.Indexes = new List<int>();
            foreach(var i in ao.Indexes)
            {
                this.Indexes.Add(i);
            }

            this.IsTerminal = ao.IsTerminal;
        }


        #endregion Contructors

        #region IDisposable Members

        public void Dispose()
        {
            if (Indexes != null) Indexes.Clear();
            Indexes = null;
            Data = null;
        }

        #endregion IDisposable Members

        public bool IsEqualTo(AlphabetObject alphabetObject)
        {
            return Data.Equals(alphabetObject.Data);
        }
    }
}